package services.kingdee

import play.api.Logging
import play.api.cache.SyncCacheApi
import play.api.libs.json.{JsArray, Json}
import utiliy.OutFilterConfig

import javax.inject.Inject
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.concurrent.{Await, ExecutionContext}
import scala.concurrent.duration._

class StockStoreNowService @Inject()(kdPost: KingdeePostV2,
                                     cache: SyncCacheApi,
                                     ofc: OutFilterConfig
                                    )(implicit exec: ExecutionContext)
  extends Logging {

  private def getData(stock: String, item: String = "") = {
    val lst: mutable.ArrayBuffer[KisStockNowtime] = mutable.ArrayBuffer()
    val limit = 2000
    var isEnd = true
    val filter = if (item.isEmpty) {
      if (stock.isEmpty) "FBaseQty<>0"
      else s"FStockId.fnumber='$stock' and FBaseQty<>0"
    } else {
      if (stock.isEmpty) s"FMaterialId.fnumber='$item' and FBaseQty<>0"
      else s"FStockId.fnumber='$stock' and FMaterialId.fnumber='$item' and FBaseQty<>0"
    }
    logger.debug(filter)
    while (isEnd) {
      val para_list = Json.obj(
        "FormId" -> "STK_Inventory",
        "FieldKeys" -> "FStockOrgId.fname,FStockId.fnumber,FStockId.fname,FMaterialId.fnumber,FMaterialName,FLot.fnumber,FBaseQty,FStockStatusId.fname",
        "FilterString" -> filter, //#"FMaterialId=829430",   # sql条件
        "OrderString" -> "",
        "TopRowCount" -> 0,
        "StartRow" -> lst.size,
        "Limit" -> limit
      )
      val res = Await.result(
        kdPost.setKdAppConfig("").executeBillQuery(para_list)
//        kdPost.post(kdPost.kingdeePostApi("Query"), parameters = Json.arr(para_list))
        , Duration.Inf)
      logger.debug(s"$res")
      val r = res
      val arr = Json.parse(r).as[Array[JsArray]]
      isEnd = arr.length != 0
      arr.foreach { f =>
        lst.append(
          KisStockNowtime(
            id = (replace(f.value(1).as[String]) + replace(f.value(3).as[String])).toLong << 8 + (f.value(5).as[String].hashCode % 256),
            kOrgName = f.value(0).as[String],
            kStockId = f.value(1).as[String],
            kStockName = f.value(2).as[String],
            kMaterialId = f.value(3).as[String],
            kMaterialName = f.value(4).as[String],
            kLot = f.value(5).as[String],
            kBaseQty = f.value(6).as[Double],
            status = f.value(7).as[String]
          )
        )
      }
    }
    lst
  }

  private def replace(string: String) = {
    val pattern = "[^0-9]".r
    pattern.replaceAllIn("000000000" + string, "0").takeRight(9)
  }

  def getNowtime(stock: String) = {
    val lst: mutable.ArrayBuffer[KisStockNowtime] = mutable.ArrayBuffer()
    val fstock = if (stock.isEmpty) ofc.getAllStockArr() else ofc.getAllStockArr().filter(_._1 == stock)
    for (i <- fstock) {
      lst ++= cache.getOrElseUpdate[ArrayBuffer[KisStockNowtime]](s"getnowtime.${i._1}", 1.hours) {
        getData(i._1)
      }
    }
    lst
  }

  def getNowtimeJson(stock: String, item: String, page: Int = 0, limit: Int = 10) = {
    logger.debug(s"getNowtime: stock=$stock,item=$item,page=$page,limit=$limit")
    val lst = if (item.isEmpty) getNowtime(stock = stock) else getData(stock, item)
    // order by id
    val lst_order = lst.sortBy(_.id)
    val length = lst_order.length
    val start = page * limit
    //    val offset = if(start+limit>length) length else start
    val res = if (start + limit > length) lst_order.drop(start) else lst_order.drop(start).take(limit)
    implicit val toJson = Json.format[KisStockNowtime]
    (Json.toJson(res), length)
  }



}

case class KisStockNowtime(id: Long, kOrgName: String, kStockId: String, kStockName: String, kMaterialId: String, kMaterialName: String, kLot: String, kBaseQty: Double,status:String){
  def name() ={
    this.status match {
      case "KCZT01_SYS" => this.copy(status = "可用")
      case "KCZT02_SYS" => this.copy(status = "待检")
      case "KCZT03_SYS" => this.copy(status = "冻结")
      case "KCZT04_SYS" => this.copy(status = "退回冻结")
      case "KCZT05_SYS" => this.copy(status = "在途")
      case "KCZT06_SYS" => this.copy(status = "收货冻结")
      case "KCZT07_SYS" => this.copy(status = "废品")
      case "KCZT08_SYS" => this.copy(status = "不良")
      case "KCZT99_SYS" => this.copy(status = "外借")
      case _ => this
    }
  }
}

